/* hc128.h
**
** Copyright (c) 2007, 2010, Meadhbh S. Hamrick
** All rights reserved.
** 
** Redistribution  and  use  in  source  and  binary  forms,  with  or  without
** modification, are permitted provided that the following conditions are met:
** 
**  * Redistributions of  source code must  retain the above  copyright notice,
**    this list of conditions and the following disclaimer.
** 
**  * Redistributions in binary form must reproduce the above copyright notice,
**    this list of conditions and the following disclaimer in the documentation
**    and/or other materials provided with the distribution.
** 
**  * Neither the  name of  Project Meadhbh  nor the names of  its contributors
**    may be used  to endorse  or promote  products derived from this  software
**    without specific prior written permission.
** 
** THIS SOFTWARE IS PROVIDED BY  THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY  EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, BUT NOT  LIMITED TO, THE
** IMPLIED WARRANTIES  OF MERCHANTABILITY AND FITNESS FOR  A PARTICULAR PURPOSE
** ARE DISCLAIMED.  IN NO  EVENT SHALL THE  COPYRIGHT OWNER OR  CONTRIBUTORS BE
** LIABLE  FOR  ANY  DIRECT,   INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
** CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,  PROCUREMENT  OF
** SUBSTITUTE GOODS  OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
** INTERRUPTION)  HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN
** CONTRACT,  STRICT LIABILITY,  OR  TORT (INCLUDING  NEGLIGENCE OR  OTHERWISE)
** ARISING IN ANY WAY  OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
** 
** $Id: hc128.h 81 2010-08-17 19:23:57Z OhMeadhbh@gmail.com $
*/

/*! \file hc128.h
 *  \brief interface for the HC-128 cipher
 *
 * HC-128 is a stream cipher designed by Hongjun Wu for the eCrypt
 * effort. It is (as far as we know) free of intellectual property
 * encumberances, fast and more secure than ARC4. This is an interface to
 * a "low level" cipher, meaning it does not manage cipher-selection
 * or memory allocation. Users may want to look at the "high level"
 * API before deciding to use this interface.
 *
 * This file provides the typedefs and function prototypes for
 * the mcrypto implementation of HC-128. This implementation
 * uses the standard initialize and update pattern for stream
 * ciphers. It does not allocate (or free) memory, but keeps
 * state on the stack and in the tMCHc128 "context" data structure.
 * 
 * Here's an example:
 *
 * \code
 *   #include <stdlib.h>
 *   #include <string.h>
 *   #include "hc128.h"
 *
 *   void hc128_example( ) {
 *     tMCHc128 *context = malloc( sizeof( tMCHc128 ) );
 *     char *key = "i am a key.";
 *     char *plaintext = "i am some plaintext";
 *     char ciphertext[128];
 *     uint32_t bytesWritten = 0;
 *
 *     if( (tMCHc128 *) NULL != context ) {
 *       memset( ciphertext, '\0', 128 );
 *       mc_stream_hc128_initialize( context, (unit8_t *) key,
 *                                   (uint32_t) strlen( key ) );
 *       mc_stream_hc128_encrypt( context, (uint8_t *) plaintext,
 *                                   (uint32_t) strlen( plaintext ), 
 *                                   (uint8_t *) ciphertext,
 *                                   128, & bytesWritten );
 *     }
 *
 *     mc_stream_hc128_clear( context );
 *  }
 * \endcode
 *
 * HC-128 is a vernam cipher, so its ciphertext is generated by XORing a
 * key-dependent "key stream" with the plaintext. The plaintext is recovered
 * by XORing the ciphertext with the same key stream. If you look carefully,
 * you'll note that both the encrypt and decrypt functions are macros
 * referencing the update function. We can do this only because we're a
 * vernam cipher.
 */

/* Macro Definitions */
#ifndef _H_HC128
#define _H_HC128

/** \def mc_stream_hc128_encrypt()
 *  \def mc_stream_hc128_decrypt()
 *
 * These are the macros that provide an encrypt() and decrypt() function
 * for this cipher. Like all vernam ciphers in this package, we just reference
 * the update() function.
 */
#define mc_stream_hc128_encrypt(c,i,il,o,ol,bw) mc_stream_hc128_update(c,i,il,o,ol,bw)
#define mc_stream_hc128_decrypt(c,i,il,o,ol,bw) mc_stream_hc128_update(c,i,il,o,ol,bw)

/* File Inclusions */

/* Typedefs, Structs, Enums, Unions */

/** \struct tMCHc128 - the HC-128 encryption context
 *
 * This data structure maintains the context of an encryption (or decryption)
 * operation. You're responsible for allocating these yourself.
 */

typedef struct {
  uint32_t a;
  uint32_t b;
  uint8_t sbox[ 256 ];
} tMCHc128;

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

  /* Function Prototypes */

  /** 
   * Copy an encryption context; copies the current state of an encryption
   * operation into another encryption context.
   *
   * \param new_context - This is where you're copying to.
   * \param old_context - This is where you're copying from.
   *
   */
  void mc_stream_hc128_clone( tMCHc128 *new_context, tMCHc128 *old_context );

  /**
   * Clear sensitive data; zeros out the encryption context to prevent data
   * leakage. Call this function on the encryption context after you've
   * finished encrypting / decrypting.
   *
   * \param context - This is the encryption context to be zeroed.
   *
   */
  void mc_stream_hc128_clear( tMCHc128 *context );

  /**
   * Initialize an encryption context with a key. This function "sets" the
   * key for the encryption context. Call this once before encrypting or
   * decrypting.
   *
   * \param context - This is the encryption context to be initialized.
   * \param key - This is the key to use.
   * \param key_length - This is the length of the key.
   *
   */
  void mc_stream_hc128_initialize( tMCHc128 *context, uint8_t *key, uint32_t key_length );

  /**
   * Encrypt or decrypt a block of data. If you use plaintext as input, this
   * function will output ciphertext. If you use ciphertext as input, this
   * function will output plaintext. This is the magic of vernam ciphers.
   *
   * \param context - This is an initialized encryption context.
   * \param input - This is the input plaintext or ciphertext.
   * \param input_length - This is the length of the input.
   * \param output - This is where the function will place the output.
   * \param output_length - This is the size of the output buffer.
   * \param bytes_written - The function will place the number of bytes written in this variable.
   */
  void mc_stream_hc128_update( tMCHc128 *context, uint8_t *input, uint32_t input_length, uint8_t *output, uint32_t output_length, uint32_t *bytes_written );

  /**
   * Generate a keystream; used by update to generate a key dependent key
   * stream. This function is normally only used by the update() function,
   * but is made available to developers who may want to use it as a
   * PRNG.
   *
   * \param context - This is the encryption context.
   * \param output - This is where the keystream will be placed.
   * \param output_length - This is the length of the output buffer.
   *
   */
  void mc_stream_hc128_keystream( tMCHc128 *context, uint8_t *output, uint32_t output_length );

  /* Global Variable Declarations */

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _H_MCRYPTO */
